package org.ccay.excel.exporter.service.impl;

import java.io.Serializable;
import java.util.Map;

import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import org.ccay.async.AsyncMessage;
import org.ccay.async.IMessageSender;
import org.ccay.async.task.ExportTaskVO;
import org.ccay.async.task.service.IExportTaskService;
import org.ccay.core.base.IExtentionAttributeSupport;
import org.ccay.core.base.PageVO;
import org.ccay.core.exception.ApplicationException;
import org.ccay.core.request.IRequestContext;
import org.ccay.core.request.impl.RequestContext;
import org.ccay.core.util.StringUtil;
import org.ccay.excel.exception.ExcelExportConstants;
import org.ccay.excel.exporter.ExportTaskRequest;
import org.ccay.excel.exporter.IExcelExportContext;
import org.ccay.excel.exporter.IExcelExportSupport;
import org.ccay.excel.exporter.service.IExcelExportAssistant;
import org.ccay.excel.exporter.service.impl.internal.ExcelExportContext;
import org.ccay.excel.exporter.service.impl.internal.ExcelStreamWriter;
import org.ccay.excel.util.impl.ExcelUtil;

/**
 * ILocalExcelExportAssistant 的实现，负责处理原生 Excel 导入
 * @author chaowangbang
 * @since 2012-5-25
 */
@Named
public class ExcelExportAssistant implements IExcelExportAssistant{
	/**
	 * 消息发送器
	 */
	@Inject
	private IMessageSender messageSender ;
	/**
	 * 任务服务
	 */
	@Inject
	private IExportTaskService exportTaskService;
	
	
	/* (non-Javadoc)
	 * @see org.ccay.excel.exporter.service.IExcelExportAssistant2#submitExportTask(java.lang.String, java.io.Serializable)
	 */
	public int submitExportTask(String excelType, Serializable condition, PageVO pageVO, Map<String, Object> parameters) throws ApplicationException {
		/*
		 * 
		 * 1.通过exportTaskService创建导出任务
		 * 2.将任务封装成ExportTaskRequest，将消息发送到异步通道
		 * 
		 */		
		ExportTaskVO exportTaskVO = new ExportTaskVO();
		//设置 exportTaskVO 属性
		String taskType = null;
		if (parameters != null) {
			Object customTaskType = parameters.get("taskType");
			if(customTaskType != null){
				taskType = customTaskType.toString();
			}
		}
		if(StringUtil.isNullOrEmpty(taskType)){
			taskType = StringUtil.firstUpperCase(StringUtil.subString4lastIndex(excelType, "."));
		}
		exportTaskVO.setMduleName(taskType);
		exportTaskVO.setExportFlag(ExcelExportConstants.STATUS_WAITING);

		// 事务定义
		DefaultTransactionDefinition transDef = new DefaultTransactionDefinition();
		transDef.setName("Excel Export");
		// 设置事务传播级别
		transDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
		
		//获取业务扩展属性 增加到任务表中
		getTaskAttr(exportTaskVO,condition);
		//创建异步处理任务
		exportTaskService.createExportTask(exportTaskVO );
	
		//构造excel导出请求信息
		ExportTaskRequest request = new ExportTaskRequest();
		IRequestContext requestContext = RequestContext.getCurrent();
		request.setUserLanguage(requestContext.getUserLanguage());
		request.setConditionObject(condition);
		request.setPageObject(pageVO);
		request.setParameters(parameters);
		request.setExcelType(excelType);		
		request.setTaskId(String.valueOf(exportTaskVO.getTaskId()));
		
		AsyncMessage message = new AsyncMessage("ExcelExport");
		message.setContent(request);
		//发送消息
		messageSender.send(message);
		return exportTaskVO.getTaskId();
	}
	
	/**
	 * 获取业务扩展属性 增加到任务表中
	 * @param exportTaskVO
	 * @param condition
	 */
	private void getTaskAttr(ExportTaskVO exportTaskVO ,Serializable condition){
		//如果业务对象 不是空 并且实现了IBaseAttrSupport 那么需要获取提供的属性给task表
		if(null != condition && condition instanceof IExtentionAttributeSupport){
			IExtentionAttributeSupport attrSupport = (IExtentionAttributeSupport)condition;
			exportTaskVO.setAttr1(attrSupport.getExtentionAttribute1());
			exportTaskVO.setAttr2(attrSupport.getExtentionAttribute2());
			exportTaskVO.setAttr3(attrSupport.getExtentionAttribute3());
			exportTaskVO.setAttr4(attrSupport.getExtentionAttribute4());
			exportTaskVO.setAttr5(attrSupport.getExtentionAttribute5());
		}
	}
	
	/**
	 * 获取支持对象
	 * @throws ApplicationException 
	 */
	public IExcelExportSupport getExportSupport(String excelType) throws ApplicationException {
		return ExcelUtil.getExportSupport(excelType);
	}

	
	/**
	 * 同步导出的方法
	 */
	public IExcelExportContext exportExcel(String excelType, Serializable condition,PageVO pageVO,
			Map<String, Object> parameters) throws ApplicationException {
		// 事务定义
		DefaultTransactionDefinition transDef = new DefaultTransactionDefinition();
		transDef.setName("Excel Export");
		// 设置事务传播级别
		transDef.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
		
	
		//构造excel导出请求信息
		ExportTaskRequest request = new ExportTaskRequest();
		IRequestContext requestContext = RequestContext.getCurrent();
		request.setUserLanguage(requestContext.getUserLanguage());
		request.setConditionObject(condition);
		request.setPageObject(pageVO);
		request.setParameters(parameters);
		request.setExcelType(excelType);		
		
		
		//导出过程
		ExcelExportContext context=new ExcelExportContext(request);
		ExcelStreamWriter writer=new ExcelStreamWriter(context);
		return writer.writer();
	}
	/**
	 * 增加对扩展参数的接口处理
	 */
	public int submitExportTask(String excelType, Serializable condition) throws ApplicationException {
		return submitExportTask(excelType,condition,null,null);
	}

	/**
	 * 增加对扩展参数的接口处理
	 */
	public IExcelExportContext exportExcel(String excelType,
			Serializable condition)
			throws ApplicationException {
		return exportExcel(excelType,condition,null);
	}
	/**
	 * 增加对筛选分页的接口处理
	 */
	public int submitExportTask(String excelType, Serializable condition,Map<String, Object> parameters)
			throws ApplicationException {
		return submitExportTask(excelType,condition,null,parameters);
	}
	/**
	 * 增加对筛选分页的接口处理
	 */
	public IExcelExportContext exportExcel(String excelType, Serializable condition, Map<String, Object> parameters) throws ApplicationException {
		return exportExcel(excelType,condition,null,parameters);
	}
}
